use anyhow::Result;
use axum::{routing::get, Router};
use std::net::SocketAddr;
use tracing::info;

mod config;
mod handlers;
mod models;
mod providers;
mod realtime;
mod services;
mod storage;
mod entitys;

#[cfg(test)]
mod integration_tests;

use providers::{CollectionData,DataProvider, ObjectData};
use services::{AuthConfig, AuthService, AuthServiceHandle, RealtimeAuthMiddleware};
use realtime::{ConnectionManager, WebSocketHandler, SSEHandler};
use realtime::connection::ConnectionManagerHandle;

#[tokio::main]
async fn main() -> Result<()> {
    // 初始化日志
    tracing_subscriber::fmt::init();
    
    // 加载配置
    let config = config::Config::load()?;
    info!("配置加载成功: {:?}", config);
    
    // 初始化数据提供者
    let data_provider = std::sync::Arc::new(DataProvider::new().await?);
    let _collection_data = std::sync::Arc::new(CollectionData::new(data_provider.storage()));
    let _object_data = std::sync::Arc::new(ObjectData::new(data_provider.storage()));
    
    // 初始化身份验证服务
    let auth_config = AuthConfig::default();
    let auth_service = AuthService::new(auth_config)?;
    let auth_service_handle = AuthServiceHandle::new(auth_service);
    let auth_middleware = RealtimeAuthMiddleware::new(auth_service_handle);
    
    // 初始化连接管理器
    let connection_manager = ConnectionManager::new(1000);
    let connection_manager_handle = ConnectionManagerHandle::new(connection_manager);
    
    // 初始化WebSocket处理器
    let websocket_handler = WebSocketHandler::new(connection_manager_handle.clone(), auth_middleware.clone());
    
    // 初始化SSE处理器
    let sse_handler = SSEHandler::new(connection_manager_handle.clone(), auth_middleware.clone());
    
    // 创建路由
    let app = Router::new()
        .route("/health", get(handlers::health_check))
        .merge(websocket_handler.create_route())
        .merge(sse_handler.create_route());
    
    // 启动服务器
    let addr: SocketAddr = config.urls.parse()?;
    info!("服务器启动在: {}", addr);
    
    let listener = tokio::net::TcpListener::bind(addr).await?;
    axum::serve(listener, app).await?;
    
    Ok(())
}